home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / nroff~06.zoo / low.c < prev    next >
C/C++ Source or Header  |  1992-07-16  |  17KB  |  1,102 lines

  1. static char *rcsid_low_c="$Id: low.c,v 1.2 1992/07/16 10:38:32 rosenkra Exp $";
  2.  
  3. /*
  4.  * $Log: low.c,v $
  5.  * Revision 1.2  1992/07/16  10:38:32  rosenkra
  6.  * port to gcc, add tm,ie,el
  7.  *
  8.  */
  9.  
  10. /*
  11.  *    low.c - misc low-level functions for nroff word processor
  12.  *
  13.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  14.  *    net:    rosenkra@convex.com
  15.  *    CIS:    71460,17
  16.  *    GENIE:    W.ROSENKRANZ
  17.  *
  18.  *    original author:
  19.  *
  20.  *    Stephen L. Browning
  21.  *    5723 North Parker Avenue
  22.  *    Indianapolis, Indiana 46220
  23.  *
  24.  *    history:
  25.  *
  26.  *    - Originally written in BDS C;
  27.  *    - Adapted for standard C by W. N. Paul
  28.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  29.  */
  30.  
  31. #undef NRO_MAIN                    /* extern globals */
  32.  
  33. #include <stdio.h>
  34. #include "nroff.h"
  35.  
  36.  
  37.  
  38. /*------------------------------*/
  39. /*    atod            */
  40. /*------------------------------*/
  41. int atod (c)
  42. char    c;
  43. {
  44.  
  45. /*
  46.  *    convert ascii character to decimal.
  47.  */
  48.  
  49.     return (((c < '0') || (c > '9')) ? -1 : c - '0');
  50. }
  51.  
  52.  
  53.  
  54.  
  55.  
  56. /*------------------------------*/
  57. /*    robrk            */
  58. /*------------------------------*/
  59. void robrk ()
  60. {
  61.  
  62. /*
  63.  *    end current filled line
  64.  */
  65.  
  66.     REGISTER char  *p, *p0;
  67.  
  68.     if (co.outp > 0)
  69.     {
  70.         /*
  71.          *   kill trailing blanks....
  72.          */
  73.         p0 = &(co.outbuf[0]);
  74.         p  = &(co.outbuf[co.outp]);
  75.         for (p--; (long) p > (long) p0; p--)
  76.         {
  77.             if (*p != ' ' && *p != '\t')
  78.                 break;
  79.             co.outp -= 1;            
  80.         }
  81.  
  82.  
  83.         /*
  84.          *   terminate line
  85.          */
  86. #ifdef NO_CR
  87.         co.outbuf[co.outp]   = '\n';
  88.         co.outbuf[co.outp+1] = EOS;
  89. #else
  90.         co.outbuf[co.outp]   = '\r';
  91.         co.outbuf[co.outp+1] = '\n';
  92.         co.outbuf[co.outp+2] = EOS;
  93. #endif
  94.  
  95.         /*
  96.          *   handle margin char (change bar) here for all filled lines
  97.          */
  98.         do_mc (co.outbuf);
  99.  
  100.         put (co.outbuf);
  101.     }
  102.     co.outp   = 0;
  103.     co.outw   = 0;
  104.     co.outwds = 0;
  105.     co.outesc = 0;
  106. }
  107.  
  108.  
  109.  
  110.  
  111. /*------------------------------*/
  112. /*    ctod            */
  113. /*------------------------------*/
  114. int ctod (p)
  115. REGISTER char  *p;
  116. {
  117.  
  118. /*
  119.  *    convert string to decimal. processes only positive values.
  120.  *    this takes a constant like "1", "1.0i", etc. 
  121.  */
  122.  
  123.     REGISTER long    val;
  124.     REGISTER int    d;
  125.     REGISTER char  *pp = p;
  126.     REGISTER char  *ptmp;
  127.     int        rside = 0;
  128.     int        lside = 0;
  129.     int        has_rside = 0;
  130.     int        has_lside = 0;
  131.  
  132.     if (*p == EOS)
  133.         return (0);
  134.  
  135.     ptmp = skipwd (pp);
  136.     pp = --ptmp;
  137.     
  138.     switch (*pp)
  139.     {
  140.     case 'i':
  141.     case 'c':
  142.         val = 0L;
  143.         while (*p != EOS && isdigit (*p))
  144.         {
  145.             has_lside++;
  146.             lside = atod (*p);
  147.             p++;
  148.             if (lside == -1)
  149.                 break;
  150.             val = 10L * val + (long) lside;
  151.         }
  152.         lside = (int) val;
  153.         if (*p == '.')
  154.         {
  155.             p++;
  156.             val = 0L;
  157.             while (*p != EOS && isdigit (*p))
  158.             {
  159.                 has_rside++;
  160.                 rside = atod (*p);
  161.                 p++;
  162.                 if (rside == -1)
  163.                     break;
  164.                 val = 10L * val + (long) rside;
  165.                 if (has_rside > 2)    /* more than enough */
  166.                     break;
  167.             }
  168.             rside = (int) val;
  169.         }
  170.  
  171.         /*
  172.          *   now put it together. 1.0i -> 240, 1.50i -> 360, etc.
  173.          */
  174.         val = 0L;
  175.         if (has_lside)
  176.         {
  177.             val = (long) lside * BU_INCH;
  178.         }
  179.         switch (has_rside)
  180.         {
  181.         case 1:
  182.             val = val + ((long) rside * BU_INCH / 10L);
  183.             break;
  184.         case 2:
  185.             val = val + ((long) rside * BU_INCH / 100L);
  186.             break;
  187.         case 3:
  188.             val = val + ((long) rside * BU_INCH / 1000L);
  189.             break;
  190.         default:
  191.             break;
  192.         }
  193.         if (*pp == 'c')
  194.             val = (val * BU_CM) / BU_INCH;
  195.  
  196.         /*
  197.          *   for now we convert to basic char size, 1 em...
  198.          */
  199.         val = val / BU_EM;
  200.  
  201.         break;
  202.  
  203.     case 'P':
  204.     case 'm':
  205.     case 'n':
  206.     case 'p':
  207.     case 'u':
  208.     case 'v':
  209.         val = 0L;
  210.         while (*p != EOS)
  211.         {
  212.             d = atod (*p);
  213.             p++;
  214.             if (d == -1)
  215.                 break;
  216.             val = 10L * val + (long) d;
  217.         }
  218.         switch (*pp)
  219.         {
  220.         case 'P':
  221.             val = val * BU_PICA;
  222.             break;
  223.         case 'p':
  224.             val = val * BU_POINT;
  225.             break;
  226.         case 'u':
  227.             val = val * BU_BU;
  228.             break;
  229.         case 'm':
  230.             val = val * BU_EM;
  231.             break;
  232.         case 'n':
  233.             val = val * BU_EN;
  234.             break;
  235.         case 'v':
  236.             val = val * BU_EM;
  237.             break;
  238.         }
  239.  
  240.         /*
  241.          *   for now we convert to basic char size, 1 em...
  242.          */
  243.         val = val / BU_EM;
  244.  
  245.         break;
  246.  
  247.     default:
  248.         /*
  249.          *   this is the default behavior. it SHOULD make things
  250.          *   compatible with the old way...
  251.          */
  252.         val = 0L;
  253.         while (*p != EOS)
  254.         {
  255.             d = atod (*p);
  256.             p++;
  257.             if (d == -1)
  258.                 break;
  259.             val = 10L * val + (long) d;
  260.         }
  261.         break;
  262.     }
  263.  
  264.     return ((int) val);
  265. }
  266.  
  267.  
  268.  
  269.  
  270. /*------------------------------*/
  271. /*    inptobu            */
  272. /*------------------------------*/
  273. void inptobu (ps)
  274. char   *ps;
  275. {
  276.  
  277. /*
  278.  *    convert input units to b.u.
  279.  */
  280.  
  281.     return;
  282. }
  283.  
  284.  
  285.  
  286.  
  287. /*------------------------------*/
  288. /*    butochar        */
  289. /*------------------------------*/
  290. void butochar (ps)
  291. char   *ps;
  292. {
  293.  
  294. /*
  295.  *    convert b.u. to char spaces
  296.  */
  297.  
  298.     return;
  299. }
  300.  
  301.  
  302.  
  303.  
  304. /*------------------------------*/
  305. /*    skipbl            */
  306. /*------------------------------*/
  307. char *skipbl (p)
  308. REGISTER char  *p;
  309. {
  310.  
  311. /*
  312.  *    skip blanks and tabs in character buffer. return ptr to first
  313.  *    non-space or non-tab char. this could mean EOS or \r or \n.
  314.  *    also increments the arg ptr (side effect).
  315.  */
  316.  
  317.     while ((*p != EOS) && (*p == ' ' || *p == '\t'))
  318.         ++p;
  319.     return (p);
  320. }
  321.  
  322.  
  323.  
  324.  
  325. /*------------------------------*/
  326. /*    skipwd            */
  327. /*------------------------------*/
  328. char *skipwd (p)
  329. REGISTER char  *p;
  330. {
  331.  
  332. /*
  333.  *    skip over word and punctuation. anything but space,\t,\r,\n, and EOS
  334.  *    is skipped. return ptr to the first of these found. also increments
  335.  *    the arg ptr (side effect).
  336.  */
  337.  
  338.     while (*p != EOS && *p != ' ' && *p != '\t' && *p != '\r' && *p != '\n')
  339.         ++p;
  340.     return (p);
  341. }
  342.  
  343.  
  344.  
  345.  
  346.  
  347. /*------------------------------*/
  348. /*    space            */
  349. /*------------------------------*/
  350. void space (n)
  351. int     n;
  352. {
  353.  
  354. /*
  355.  *    space vertically n lines. this does header and footer also.
  356.  */
  357.  
  358.     robrk ();
  359.     if (pg.lineno > pg.bottom)
  360.         return;
  361.     if (pg.lineno == 0)
  362.         phead ();
  363.     skip (min (n, pg.bottom + 1 - pg.lineno));
  364.     pg.lineno += n;
  365.     set_ireg ("ln", pg.lineno, 0);
  366.     if (pg.lineno > pg.bottom)
  367.         pfoot ();
  368. }
  369.  
  370.  
  371.  
  372.  
  373. /*------------------------------*/
  374. /*    getfield        */
  375. /*------------------------------*/
  376. char *getfield (p, q, delim)
  377. REGISTER char  *p;
  378. REGISTER char  *q;
  379. char        delim;
  380. {
  381.  
  382. /*
  383.  *    get field from title
  384.  */
  385.  
  386.     while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS)
  387.     {
  388.         *q++ = *p++;
  389.     }
  390.     *q = EOS;
  391.     if (*p == delim)
  392.         ++p;
  393.     return (p);
  394. }
  395.  
  396.  
  397.  
  398.  
  399.  
  400. /*------------------------------*/
  401. /*    getwrd            */
  402. /*------------------------------*/
  403. int getwrd (p0, p1)
  404. REGISTER char  *p0;
  405. REGISTER char  *p1;
  406. {
  407.  
  408. /*
  409.  *    get non-blank word from p0 into p1.
  410.  *    return number of characters processed.
  411.  */
  412.  
  413.     REGISTER int    i;
  414.     REGISTER char  *p;
  415.     char        c;
  416.  
  417.     /*
  418.      *   init counter...
  419.      */
  420.     i = 0;
  421.  
  422.  
  423.     /*
  424.      *   skip leading whitespace
  425.      */
  426.     while (*p0 && (*p0 == ' ' || *p0 == '\t'))
  427.     {
  428.         ++i;
  429.         ++p0;
  430.     }
  431.  
  432.  
  433.     /*
  434.      *   set ptr and start to look for end of word
  435.      */
  436.     p = p0;
  437.     while (*p0 != ' ' && *p0 != EOS && *p0 != '\t')
  438.     {
  439.         if (*p0 == '\n' || *p0 == '\r')
  440.             break;
  441.         *p1 = *p0++;
  442.         ++p1;
  443.         ++i;
  444.     }
  445.  
  446.     c = *(p1 - 1);
  447.     if (c == '\"')
  448.         c = *(p1 - 2);
  449.     if (c == '?' || c == '!')
  450.     {
  451.         *p1++ = ' ';
  452.         ++i;
  453.     }
  454.     if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower (*p)))
  455.     {
  456.         *p1++ = ' ';
  457.         ++i;
  458.     }
  459.     *p1 = EOS;
  460.  
  461.     return (i);
  462. }
  463.  
  464.  
  465.  
  466.  
  467. /*------------------------------*/
  468. /*    countesc        */
  469. /*------------------------------*/
  470.  
  471. #define ESC            27
  472.  
  473. int countesc (p)
  474. REGISTER char  *p;
  475. {
  476.  
  477. /*
  478.  *    count escape sequence characters in given null-terminated string.
  479.  *    we try and interpret the escape sequence, and if we recognize it,
  480.  *    we count the total number of chars in the sequence, including the
  481.  *    ESC itself. e.g. "ESC [ 1 m" is 4. we do this for the entire string.
  482.  *
  483.  *    the results are used when adjusting the margins, so we ignore the
  484.  *    additional chars added. the escape sequence should not be broken
  485.  *    up by this process, since we only add extra space(s) next to a
  486.  *    space.
  487.  */
  488.  
  489.     REGISTER char  *pp;
  490.     REGISTER int    num;
  491.  
  492.  
  493.     /*
  494.      *  initialize string pointer and count
  495.      */
  496.     pp  = p;
  497.     num = 0;
  498.  
  499.  
  500.     /*
  501.      *   do entire string...
  502.      */
  503.     while (*pp != EOS)
  504.